package application;

import contracts.responses.ForcedOfflineResponse;
import contracts.responses.OnlineUserCountResponse;
import domain.entities.User;
import eventbus.PageEventBus;
import eventbus.events.UserLoginEvent;
import eventbus.events.UserLogoutEvent;
import internal.UserLoggedInfo;
import network.websocket.WSServerSender;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 对已经登录的用户进行管理
 *
 * @author wyl
 */
public class UserLoggedManager {

    // k:userId v:connId
    private static final ConcurrentHashMap<String, String> UidCidMap = new ConcurrentHashMap<>();

    //登录用户字典 k:connId
    private static final ConcurrentHashMap<String, UserLoggedInfo> CidUserInfoMap = new ConcurrentHashMap<>();


    public static void login(String connId, User user) {
        //检查用户是否已经登录,若已经登录过则进行下线处理
        String userId = user.getId();
        String oldConnId = UidCidMap.get(userId);
        if (oldConnId != null) {
            CidUserInfoMap.remove(oldConnId);
            WSServerSender.send(oldConnId, new ForcedOfflineResponse("您的账号已经在别处登录..."));
        }
        System.out.println(connId + "登录了");
        //更新在线用户界面,更新在线用户数量
        UserLoggedInfo info = new UserLoggedInfo(connId, user);
        CidUserInfoMap.put(connId, info);
        UidCidMap.put(userId, connId);
        PageEventBus.publish(new UserLoginEvent(info));
        sendLoggedAll(new OnlineUserCountResponse(getUserCount()));
    }

    public static void logout(String connId) {
        if (CidUserInfoMap.containsKey(connId)) {
            System.out.println(connId + "退出了");
            UserLoggedInfo info = CidUserInfoMap.remove(connId);
            String userId = info.getUserId();
            UidCidMap.remove(userId);
            //更新在线用户界面
            PageEventBus.publish(new UserLogoutEvent(userId));
            //更新用户数量
            sendLoggedAll(new OnlineUserCountResponse(getUserCount()));
        }
    }

    public static void sendLoggedAll(Object resp) {
        //获取已经登录的用户id集合(包括自己)
        Collection<String> loginUserIds = UidCidMap.values();
        //向这些用户发送消息（响应）
        loginUserIds.forEach(connId -> WSServerSender.send(connId, resp));
    }

    public static int getUserCount() {
        return CidUserInfoMap.size();
    }

    public static Collection<UserLoggedInfo> getAllUserLoggedInfo() {
        return CidUserInfoMap.values();
    }

    public static UserLoggedInfo getUserLoggedInfo(String connId) {
        if (CidUserInfoMap.containsKey(connId)) {
            return CidUserInfoMap.get(connId);
        }
        return null;
    }

    public static UserLoggedInfo getUserLoggedInfoByUserId(String userId) {
        if (UidCidMap.containsKey(userId)) {
            String connId = UidCidMap.get(userId);
            return getUserLoggedInfo(connId);
        }
        return null;
    }


}
